package com.ssy.lingxi.product.serviceImpl.customer;

import cn.hutool.core.bean.BeanUtil;
import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.product.api.model.request.CustomerAttributeValueRequest;
import com.ssy.lingxi.product.api.model.request.GoodsRequest;
import com.ssy.lingxi.product.api.model.request.SimpleIdListRequest;
import com.ssy.lingxi.product.api.model.request.SimpleIdRequest;
import com.ssy.lingxi.product.api.model.request.commodity.CommodityAddRequest;
import com.ssy.lingxi.product.api.model.request.commodity.CommodityAttributeRequest;
import com.ssy.lingxi.product.api.model.response.SimpleAttributeValueResponse;
import com.ssy.lingxi.product.api.model.response.SimpleCustomerAttributeResponse;
import com.ssy.lingxi.product.common.enums.CommodityAttributeTypeEnum;
import com.ssy.lingxi.product.entity.customer.CustomerAttribute;
import com.ssy.lingxi.product.entity.customer.CustomerAttributeGroup;
import com.ssy.lingxi.product.entity.customer.CustomerAttributeValue;
import com.ssy.lingxi.product.entity.platform.Attribute;
import com.ssy.lingxi.product.entity.platform.AttributeValue;
import com.ssy.lingxi.product.repository.commodity.CommodityRepository;
import com.ssy.lingxi.product.repository.customer.CustomerAttributeGroupRepository;
import com.ssy.lingxi.product.repository.customer.CustomerAttributeRepository;
import com.ssy.lingxi.product.repository.customer.CustomerAttributeValueRepository;
import com.ssy.lingxi.product.repository.platform.AttributeValueRepository;
import com.ssy.lingxi.product.service.customer.ICustomerAttributeValueService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 属性值实现类
 *
 * @author jw.chen
 * @version 2.0.0
 * @date 2020/6/23
 */
@Service
public class CustomerAttributeValueServiceImpl implements ICustomerAttributeValueService {

    @Autowired
    private CustomerAttributeRepository customerAttributeRepository;

    @Autowired
    private CustomerAttributeValueRepository customerAttributeValueRepository;

    @Autowired
    private AttributeValueRepository attributeValueRepository;

    @Autowired
    private CommodityRepository commodityRepository;

    @Autowired
    private CustomerAttributeGroupRepository customerAttributeGroupRepository;

    /**
     * 同步平台后台属性
     *
     * @param simpleIdListRequest 平台后台属性值id集合
     * @return 操作结果
     */
    @Transactional
    @Override
    public Boolean syncAttributeValue(UserLoginCacheDTO sysUser, SimpleIdListRequest simpleIdListRequest) {
        List<Long> idList = simpleIdListRequest.getIdList();
        List<AttributeValue> attributeValueList = attributeValueRepository.findByIdIn(idList);
        List<CustomerAttributeValue> nameList = customerAttributeValueRepository.findByMemberIdAndMemberRoleId(sysUser.getMemberId(), sysUser.getMemberRoleId());
        Set<String> nameSet = nameList.stream().map(customerAttributeValue -> {
            CustomerAttribute customerAttribute = customerAttributeValue.getCustomerAttribute();
            if (customerAttribute != null) {
                String groupName = customerAttribute.getGroupName();
                String attributeName = customerAttribute.getName();
                String value = customerAttributeValue.getValue();
                return groupName + Constants.SPLIT_STR_FULL_ID + attributeName + Constants.SPLIT_STR_FULL_ID + value;
            } else {
                return null;
            }
        }).filter(Objects::nonNull).collect(Collectors.toSet());
        //判断名称是否出现重复
        for (AttributeValue attributeValue : attributeValueList) {
            Attribute attribute = attributeValue.getAttribute();
            String groupName = attribute.getGroupName();
            String attributeName = attribute.getName();
            String value = attributeValue.getValue();
            String fullName = groupName + Constants.SPLIT_STR_FULL_ID + attributeName + Constants.SPLIT_STR_FULL_ID + value;
            if (nameSet.contains(fullName)) {
                throw new BusinessException(ResponseCode.PRODUCT_SYNC_ATTRIBUTE_VALUE_EXIST);
            }
        }
        //定时临时变量
        HashMap<String, CustomerAttribute> attributeMap = new HashMap<>();
        HashMap<String, Long> groupMap = new HashMap<>();
        List<CustomerAttributeValue> customerAttributeValueList = attributeValueList.stream().map(attributeValue -> {
            CustomerAttributeValue customerAttributeValue = new CustomerAttributeValue();
            customerAttributeValue.setAttributeValue(attributeValue);
            customerAttributeValue.setValue(attributeValue.getValue());
            customerAttributeValue.setImageUrl(attributeValue.getImageUrl());
            customerAttributeValue.setIsEnable(attributeValue.getIsEnable());
            customerAttributeValue.setMemberId(sysUser.getMemberId());
            customerAttributeValue.setMemberName(sysUser.getCompany());
            customerAttributeValue.setMemberRoleId(sysUser.getMemberRoleId());
            customerAttributeValue.setMemberRoleName(sysUser.getMemberRoleName());
            customerAttributeValue.setUserId(sysUser.getUserId());
            customerAttributeValue.setUserName(sysUser.getUserName());
            customerAttributeValue.setCreateTime(System.currentTimeMillis());

            //判断属性名是否存在，不存在则新增
            String attributeName = attributeValue.getAttribute().getName();
            CustomerAttribute customerAttribute = attributeMap.get(attributeName);
            if (customerAttribute != null) {
                customerAttributeValue.setCustomerAttribute(customerAttribute);
            } else {
                List<CustomerAttribute> customerAttributeList = customerAttributeRepository.findByMemberIdAndMemberRoleIdAndName(sysUser.getMemberId(), sysUser.getMemberRoleId(), attributeName);
                if (customerAttributeList != null && customerAttributeList.size() > 0) {
                    customerAttribute = customerAttributeList.get(0);
                } else {
                    Attribute attribute = attributeValue.getAttribute();
                    customerAttribute = new CustomerAttribute();
                    customerAttribute.setAttribute(attribute);
                    customerAttribute.setName(attribute.getName());
                    customerAttribute.setIsArea(attribute.getIsArea());
                    customerAttribute.setIsDate(attribute.getIsDate());
                    customerAttribute.setIsEmpty(attribute.getIsEmpty());
                    customerAttribute.setIsEnable(attribute.getIsEnable());
                    customerAttribute.setIsPrice(attribute.getIsPrice());
                    customerAttribute.setIsSearch(attribute.getIsSearch());
                    customerAttribute.setType(attribute.getType());
                    customerAttribute.setMemberId(sysUser.getMemberId());
                    customerAttribute.setMemberName(sysUser.getCompany());
                    customerAttribute.setMemberRoleId(sysUser.getMemberRoleId());
                    customerAttribute.setMemberRoleName(sysUser.getMemberRoleName());
                    customerAttribute.setUserId(sysUser.getUserId());
                    customerAttribute.setUserName(sysUser.getUserName());
                    customerAttribute.setCreateTime(System.currentTimeMillis());
                    //判断属性组名是否存在，不存在则新增
                    String groupName = attribute.getGroupName();
                    Long groupId = groupMap.get(groupName);
                    if (groupId != null && groupId > 0) {
                        customerAttribute.setGroupId(groupId);
                        customerAttribute.setGroupName(groupName);
                    } else {
                        CustomerAttributeGroup customerAttributeGroup = customerAttributeGroupRepository.findFirstByMemberIdAndMemberRoleIdAndName(sysUser.getMemberId(), sysUser.getMemberRoleId(), groupName);
                        if (customerAttributeGroup == null) {
                            customerAttributeGroup = new CustomerAttributeGroup();
                            customerAttributeGroup.setName(groupName);
                            customerAttributeGroup.setMemberId(sysUser.getMemberId());
                            customerAttributeGroup.setMemberName(sysUser.getCompany());
                            customerAttributeGroup.setMemberRoleId(sysUser.getMemberRoleId());
                            customerAttributeGroup.setMemberRoleName(sysUser.getMemberRoleName());
                            customerAttributeGroup.setUserId(sysUser.getUserId());
                            customerAttributeGroup.setUserName(sysUser.getUserName());
                            customerAttributeGroupRepository.saveAndFlush(customerAttributeGroup);
                        }
                        customerAttribute.setGroupId(customerAttributeGroup.getId());
                        customerAttribute.setGroupName(customerAttributeGroup.getName());
                        groupMap.put(customerAttributeGroup.getName(), customerAttributeGroup.getId());
                    }
                }
                customerAttributeValue.setCustomerAttribute(customerAttribute);
                attributeMap.put(attributeName, customerAttribute);
            }
            return customerAttributeValue;
        }).collect(Collectors.toList());

        customerAttributeValueRepository.saveAll(customerAttributeValueList);
        return true;
    }

    /**
     * 查询属性值
     *
     * @param pageVO 分页参数
     * @param customerAttributeId 会员属性id
     * @param value 值
     * @return Page<Attribute>
     */
    @Override
    public Page<CustomerAttributeValue> getCustomerAttributeValueList(UserLoginCacheDTO sysUser, PageVO pageVO, Long customerAttributeId, String value) {
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize());
        return customerAttributeValueRepository.findByMemberIdAndMemberRoleIdAndValueContainingAndCustomerAttributeIdOrderByIdDesc(sysUser.getMemberId(), sysUser.getMemberRoleId(), value, customerAttributeId, page);
    }

    /**
     * 查询属性值
     *
     * @return id
     */
    @Override
    public CustomerAttributeValue getCustomerAttributeValue(UserLoginCacheDTO sysUser, Long id) {
        return customerAttributeValueRepository.findById(id).orElse(null);
    }

    /**
     * 添加/修改属性值
     *
     * @param customerAttributeValueRequest 请求参数
     * @return 操作结果
     */
    @Transactional
    @Override
    public Long saveOrUpdateCustomerAttributeValue(UserLoginCacheDTO sysUser, CustomerAttributeValueRequest customerAttributeValueRequest){
        Long memberId = sysUser.getMemberId();
        Long memberRoleId = sysUser.getMemberRoleId();
        Long userId = sysUser.getUserId();
        Long id = customerAttributeValueRequest.getId();
        String value = customerAttributeValueRequest.getValue();
        CustomerAttribute customerAttribute;
        SimpleCustomerAttributeResponse customerAttributeResponse = customerAttributeValueRequest.getCustomerAttribute();
        if(customerAttributeResponse != null){
            //判断属性是否存在并且启用
            customerAttribute = customerAttributeRepository.findById(customerAttributeResponse.getId()).orElse(null);
            if(customerAttribute != null){
                Boolean isEnable = customerAttribute.getIsEnable();
                if(!isEnable){
                    throw new BusinessException(ResponseCode.PRODUCT_ATTRIBUTE_NOT_ENABLE);
                }
            }else{
                throw new BusinessException(ResponseCode.PRODUCT_ATTRIBUTE_NOT_EXIST);
            }
        }else{
            throw new BusinessException(ResponseCode.PRODUCT_ATTRIBUTE_NOT_EXIST);
        }
        Long customerAttributeId = customerAttributeResponse.getId();
        List<CustomerAttributeValue> customerAttributeValueList;
        CustomerAttributeValue customerAttributeValue = new CustomerAttributeValue();
        //判断属性值名称是否重复
        if(id != null && id > 0){
            CustomerAttributeValue currentCustomerAttributeValue = customerAttributeValueRepository.findById(id).orElse(null);
            if(currentCustomerAttributeValue == null){
                throw new BusinessException(ResponseCode.PRODUCT_ATTRIBUTE_VALUE_NOT_EXIST);
            }
            customerAttributeValueList = customerAttributeValueRepository.findByMemberIdAndMemberRoleIdAndCustomerAttributeIdAndValueAndIdNot(memberId, memberRoleId, customerAttributeId, value, id);
        }else{
            customerAttributeValueList = customerAttributeValueRepository.findByMemberIdAndMemberRoleIdAndCustomerAttributeIdAndValue(memberId, memberRoleId, customerAttributeId, value);
        }
        if(!customerAttributeValueList.isEmpty()){
            throw new BusinessException(ResponseCode.PRODUCT_ATTRIBUTE_VALUE_NAME_EXIST);
        }
        BeanUtil.copyProperties(customerAttributeValueRequest, customerAttributeValue);
        customerAttributeValue.setMemberId(memberId);
        customerAttributeValue.setMemberName(sysUser.getCompany());
        customerAttributeValue.setMemberRoleId(memberRoleId);
        customerAttributeValue.setMemberRoleName(sysUser.getMemberRoleName());
        customerAttributeValue.setUserId(userId);
        customerAttributeValue.setUserName(sysUser.getUserName());
        //判断平台属性值是否存在并启用
        SimpleAttributeValueResponse attributeValueResponse = customerAttributeValueRequest.getAttributeValue();
        if(attributeValueResponse != null){
            AttributeValue attributeValue = attributeValueRepository.findById(attributeValueResponse.getId()).orElse(null);
            if(attributeValue != null){
                Boolean isEnable = attributeValue.getIsEnable();
                if(!isEnable){
                    throw new BusinessException(ResponseCode.PRODUCT_PLATFORM_ATTRIBUTE_VALUE_NOT_ENABLE);
                }
            }else{
                throw new BusinessException(ResponseCode.PRODUCT_PLATFORM_ATTRIBUTE_VALUE_NOT_EXIST);
            }
            customerAttributeValue.setAttributeValue(attributeValue);
        }

        customerAttributeValueList.add(customerAttributeValue);
        customerAttribute.setCustomerAttributeValueList(customerAttributeValueList);
        //数据库持久化对象
        customerAttribute.setMemberId(memberId);
        customerAttribute.setMemberName(sysUser.getCompany());
        customerAttribute.setMemberRoleId(memberRoleId);
        customerAttribute.setMemberRoleName(sysUser.getMemberRoleName());
        customerAttribute.setUserId(userId);
        customerAttribute.setUserName(sysUser.getUserName());
        customerAttributeRepository.saveAndFlush(customerAttribute);
        return customerAttribute.getCustomerAttributeValueList().get(0).getId();
    }

    /**
     * 删除属性值
     *
     * @param id id
     * @return 操作结果
     */
    @Override
    public String deleteCustomerAttributeValue(UserLoginCacheDTO sysUser, Long id) {
        CustomerAttributeValue customerAttributeValue = customerAttributeValueRepository.findById(id).orElse(null);
        if(customerAttributeValue != null){
            Boolean isEnable = customerAttributeValue.getIsEnable();
            if(!isEnable){
                customerAttributeValueRepository.deleteById(id);
                return ResponseCode.SUCCESS.getMessage();
            }else{
                throw new BusinessException(ResponseCode.PRODUCT_ENABLE_NOT_DELETE);
            }
        }
        throw new BusinessException(ResponseCode.PRODUCT_ATTRIBUTE_VALUE_NOT_EXIST);
    }

    /**
     * 启用/停用属性值
     *
     * @param id id
     * @param status status
     * @return 操作结果
     */
    @Override
    public String updateCustomerAttributeValueStatus(UserLoginCacheDTO sysUser, Long id, Boolean status){
        //验证数据库中是否存在该数据
        CustomerAttributeValue customerCustomerAttributeValue = customerAttributeValueRepository.findById(id).orElse(null);
        if(customerCustomerAttributeValue != null){
            if(!status) {
                //判断是否有商品还在使用
                Integer count = commodityRepository.findCommodityCountByCustomerAttributeValueId(id);
                if (count > 0) {
                    throw new BusinessException(ResponseCode.PRODUCT_COMMODITY_RELATION_NOT_STOP);
                }
            }
            //持久化数据
            customerCustomerAttributeValue.setIsEnable(status);
            customerAttributeValueRepository.saveAndFlush(customerCustomerAttributeValue);
            return ResponseCode.SUCCESS.getMessage();
        }
        throw new BusinessException(ResponseCode.PRODUCT_ATTRIBUTE_VALUE_NOT_EXIST);
    }

    /**
     * 判断是否有自定义属性，有的话先新增(商品)
     *
     * @param sysUser          当前登录用户
     * @param commodityRequest 请求参数
     */
    @Override
    public void saveCustomerAttributeValue(UserLoginCacheDTO sysUser, CommodityAddRequest commodityRequest) {
        this.saveCustomerAttributeValueCommon(sysUser, commodityRequest.getCommodityAttributeList());
    }

    /**
     * 判断是否有自定义属性，有的话先新增(物料)
     *
     * @param sysUser      当前操作用户
     * @param goodsRequest 请求参数
     */
    @Override
    public void saveGoodsCustomerAttributeValue(UserLoginCacheDTO sysUser, GoodsRequest goodsRequest) {
        this.saveCustomerAttributeValueCommon(sysUser, goodsRequest.getCommodityAttributeList());
    }

    /**
     * 商品/物料保存属性公用方法
     *
     * @param sysUser                当前登录用户
     * @param commodityAttributeList 请求参数
     */
    public void saveCustomerAttributeValueCommon(UserLoginCacheDTO sysUser, List<CommodityAttributeRequest> commodityAttributeList) {
        List<CustomerAttributeValue> customerAttributeValueList = new ArrayList<>();
        if (CollectionUtils.isEmpty(commodityAttributeList)) {
            return;
        }
        commodityAttributeList.forEach(commodityAttributeRequest -> {
            SimpleIdRequest customerAttributeId = commodityAttributeRequest.getCustomerAttribute();
            if(customerAttributeId != null){
                CustomerAttribute customerAttribute = customerAttributeRepository.findById(customerAttributeId.getId()).orElse(null);
                if(customerAttribute != null){
                    Integer type = customerAttribute.getType();
                    if(CommodityAttributeTypeEnum.Input.getCode().equals(type)){
                        List<com.ssy.lingxi.product.api.model.request.commodity.CustomerAttributeValueRequest> customerAttributeValueRequestList = commodityAttributeRequest.getCustomerAttributeValueList();
                        customerAttributeValueRequestList.forEach(customerAttributeValueRequest -> {
                            String value = customerAttributeValueRequest.getValue();
                            if(StringUtils.isNotEmpty(value)){
                                CustomerAttributeValue customerAttributeValue = customerAttributeValueRepository.findFirstByMemberIdAndMemberRoleIdAndValue(sysUser.getMemberId(), sysUser.getMemberRoleId(), value);
                                if(customerAttributeValue == null){
                                    customerAttributeValue = new CustomerAttributeValue();
                                    customerAttributeValue.setValue(value);
                                    customerAttributeValue.setMemberId(sysUser.getMemberId());
                                    customerAttributeValue.setMemberName(sysUser.getCompany());
                                    customerAttributeValue.setMemberRoleId(sysUser.getMemberRoleId());
                                    customerAttributeValue.setMemberRoleName(sysUser.getMemberRoleName());
                                    customerAttributeValue.setUserId(sysUser.getUserId());
                                    customerAttributeValue.setUserName(sysUser.getUserName());
                                    customerAttributeValueList.add(customerAttributeValue);
                                }
                            }
                        });
                    }
                }
            }
        });
        if(customerAttributeValueList.size() > 0){
            customerAttributeValueRepository.saveAll(customerAttributeValueList);
        }
    }
}

